package com.wayne.resthandler;

import com.wayne.beans.MethodInfo;
import com.wayne.beans.ServerInfo;
import com.wayne.interfaces.RestHandler;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
import reactor.core.publisher.Mono;

import static org.springframework.http.MediaType.APPLICATION_JSON;

public class WebClientRestHandler implements RestHandler {
    private WebClient client;

    /**
     * 初始化WebClient
     *
     * @param serverInfo
     */
    @Override
    public void init(ServerInfo serverInfo) {
        this.client = WebClient.create(serverInfo.getUrl());
    }

    /**
     * 处理rest请求
     *
     * @param methodInfo
     * @return
     */
    @Override
    public Object invokeRest(MethodInfo methodInfo) {
        //返回结果
        Object result = null;
        RequestBodySpec reuqest = client
                //请求方法
                .method(methodInfo.getMethod())
                //请求url和参数
                .uri(methodInfo.getUrl(), methodInfo.getParams())
                //格式
                .accept(APPLICATION_JSON);
        ResponseSpec retrieve = null;
        //发出请求
        if (methodInfo.getBody() != null) {
            retrieve = reuqest.body(methodInfo.getBody(), methodInfo.getBodyElementType()).retrieve();
        } else {
            retrieve = reuqest.retrieve();
        }
        //处理异常
        retrieve.onStatus(httpStatus -> httpStatus.value()==404,clientResponse -> Mono.just(new RuntimeException("404异常")));
        //处理body
        if (methodInfo.isReturnFlux()) {
            result = retrieve.bodyToFlux(methodInfo.getReturnElementType());
        } else {
            result = retrieve.bodyToMono(methodInfo.getReturnElementType());
        }
        return result;
    }
}
